home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / tnos / tnos100s / lapb.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-19  |  22.1 KB  |  853 lines

  1. /* Link Access Procedures Balanced (LAPB), the upper sublayer of
  2.  * AX.25 Level 2.
  3.  * Copyright 1991 Phil Karn, KA9Q
  4.  *
  5.  * 92/02/07 WG7J
  6.  * Modified to drop ax.25 route records in cases where routes
  7.  * were added by the connections. Inspired by K4TQL
  8.  */
  9. #include "global.h"
  10. #include "config.h"
  11. #ifdef AX25
  12. #include "mbuf.h"
  13. #include "timer.h"
  14. #include "ax25.h"
  15. #include "lapb.h"
  16. #include "ip.h"
  17. #include "netrom.h"
  18.  
  19. /* This forces data sent by jumpstarting a mailbox connect to
  20.  * resend the header etc. when the first UA reply is missed, and
  21.  * a second SABM is received for the same connection
  22.  * added by Ron Murray VK6ZJM, Murray_RJ@cc.curtin.edu.au
  23.  */
  24. #define SABM_HOLDOFF
  25.  
  26. static void handleit __ARGS((struct ax25_cb *axp,int pid,struct mbuf *bp));
  27. static void procdata __ARGS((struct ax25_cb *axp,struct mbuf *bp));
  28. static int ackours __ARGS((struct ax25_cb *axp,int16 n));
  29. static void clr_ex __ARGS((struct ax25_cb *axp));
  30. static void enq_resp __ARGS((struct ax25_cb *axp));
  31. static void inv_rex __ARGS((struct ax25_cb *axp));
  32.  
  33. /*needed for mailbox jumpstart - WG7J */
  34. #ifdef MAILBOX
  35. #ifdef NETROM
  36. extern struct nrnbr_tab *find_nrnbr __ARGS((char *, unsigned));
  37. #endif
  38. extern int Mbjumpstart;
  39. extern struct no_js *Exclude;
  40. #endif
  41.  
  42. /*If we have an AX.25 AUTO route record, drop it.*/
  43. static void
  44. drop_axr(axp)
  45. struct ax25_cb *axp;
  46. {
  47.     struct ax_route *axr;
  48.  
  49.     axr = ax_lookup(axp->remote,axp->iface);
  50.     if(axr != NULLAXR && axr->type != AX_LOCAL)
  51.         ax_drop(axp->remote,axp->iface);
  52. }
  53.  
  54. /* Process incoming frames */
  55. int
  56. lapb_input(axp,cmdrsp,bp)
  57. struct ax25_cb *axp;        /* Link control structure */
  58. int cmdrsp;            /* Command/response flag */
  59. struct mbuf *bp;        /* Rest of frame, starting with ctl */
  60. {
  61.     int control;
  62.     int class;        /* General class (I/S/U) of frame */
  63.     int16 type;        /* Specific type (I/RR/RNR/etc) of frame */
  64.     char pf;        /* extracted poll/final bit */
  65.     char poll = 0;
  66.     char final = 0;
  67.     int16 nr;        /* ACK number of incoming frame */
  68.     int16 ns;        /* Seq number of incoming frame */
  69.     int16 tmp;
  70. #ifdef MAILBOX
  71. #ifdef NETROM
  72.     int ifnum;      /*used to find possible netrom connect*/
  73. #endif
  74.     struct no_js *ep;   /*scan the 'exclude-calls' list */
  75. #endif
  76.  
  77.     if(bp == NULLBUF || axp == NULLAX25){
  78.         free_p(bp);
  79.         return -1;
  80.     }
  81.  
  82.     /* Extract the various parts of the control field for easy use */
  83.     if((control = PULLCHAR(&bp)) == -1){
  84.         free_p(bp);    /* Probably not necessary */
  85.         return -1;
  86.     }
  87.     type = ftype(control);
  88.     class = type & 0x3;
  89.     pf = control & PF;
  90.     /* Check for polls and finals */
  91.     if(pf){
  92.         switch(cmdrsp){
  93.         case LAPB_COMMAND:
  94.             poll = YES;
  95.             break;
  96.         case LAPB_RESPONSE:
  97.             final = YES;
  98.             break;
  99.         }
  100.     }
  101.     /* Extract sequence numbers, if present */
  102.     switch(class){
  103.     case I:
  104.     case I+2:
  105.         ns = (control >> 1) & MMASK;
  106.     case S:    /* Note fall-thru */
  107.         nr = (control >> 5) & MMASK;
  108.         break;
  109.     }
  110.     /* This section follows the SDL diagrams by K3NA fairly closely */
  111.     switch(axp->state){
  112.     case LAPB_DISCONNECTED:
  113.         switch(type){
  114.         case SABM:    /* Initialize or reset link */
  115.             /* This a new incoming connection.
  116.              * Accept if we have enough memory left
  117.              * 920115 - WG7J
  118.              */
  119.             if(availmem() < Memthresh){
  120.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  121.                 break;
  122.             }
  123.             sendctl(axp,LAPB_RESPONSE,UA|pf);   /* Always accept */
  124.             clr_ex(axp);
  125.             axp->unack = axp->vr = axp->vs = 0;
  126.             lapbstate(axp,LAPB_CONNECTED);/* Resets state counters */
  127.             axp->srt = Axirtt;
  128.             axp->mdev = 0;
  129.             set_timer(&axp->t1,2*axp->srt);
  130.             start_timer(&axp->t3);
  131.             start_timer(&axp->t4);
  132. #ifdef SABM_HOLDOFF
  133.             axp->flags.rxd_I_frame = 0;    /* nothing received yet */
  134. #endif
  135.             /*Jump-start the mailbox. This causes the [NET-H$] prompt to
  136.              *be sent Immediately, instead of after the first data packet
  137.              *Check for connections from known netrom calls,
  138.              *calls from the 'jumpstart exclude' list and check if interface
  139.              *is in vc mode...
  140.              *we don't want to start the mailbox in these cases,
  141.              *since these could be attempts to do level 3 stuff.
  142.              *12/09/91 WG7J
  143.              */
  144. #ifdef MAILBOX
  145.         if (axp->jumpstarted & IP_LINK)
  146.         break;
  147.             if(Mbjumpstart) {
  148. #ifdef NETROM
  149.                 if(axp->jumpstarted == NETROM_LINK) {
  150.                     /* check if the incoming interface is enabled for netrom*/
  151.                     if(axp->iface->flags & IS_NR_IFACE)
  152.                         if(find_nrnbr(axp->remote,axp->iface) != NULLNTAB)
  153.                             /* this is a netrom neighbour*/
  154.                             break;
  155.                 }
  156. #endif /* NETROM */
  157.                 /*Now check the 'exclude' list*/
  158.                 for(ep=Exclude;ep!=(struct no_js *)NULL;ep=ep->next)
  159.                     if(addreq(axp->remote,ep->call))
  160.                         break;
  161.                 if(ep != (struct no_js *)NULL) /*exclude this one*/
  162.                     break;
  163.  
  164. #ifdef nope
  165.                 /*if the interface mode = VC, then DO NOT do it,
  166.                  * this could be a VC attempted by IP!
  167.                  */
  168.                 if(!(axp->iface->flags & CONNECT_MODE)) {
  169. #endif
  170.                     /*We passed all tests!*/
  171.                     axp->jumpstarted += JUMPSTARTED;
  172.                     s_arcall(axp,0);
  173. #ifdef nope
  174.                 }
  175. #endif
  176.             }
  177. #endif /* MAILBOX */
  178.             break;
  179.         case DISC:    /* Always answer a DISC with a DM */
  180.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  181.             break;
  182.         case DM:    /* Ignore to avoid infinite loops */
  183.             break;
  184.         default:    /* All others get DM */
  185.             if(poll)
  186.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  187.             break;
  188.         }
  189.         if(axp->state == LAPB_DISCONNECTED){    /* we can close connection */
  190.             stop_timer(&axp->t1);    /* waste all the timers */
  191.             stop_timer(&axp->t3);
  192.             stop_timer(&axp->t4);
  193.             free_q(&axp->txq);    /* lose transmit queue */
  194.             drop_axr(axp);        /* drop ax25 route */
  195.             del_ax25(axp);      /* clean out the trash */
  196.             free_p(bp);
  197.         }
  198.         break;
  199.     case LAPB_SETUP:
  200.         switch(type){
  201.         case SABM:    /* Simultaneous open */
  202.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  203.             break;
  204.         case DISC:
  205.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  206. #ifdef NETROM
  207.             nr_derate(axp);
  208. #endif
  209.             drop_axr(axp);      /* drop ax25 route */
  210.             free_q(&axp->txq);
  211.             stop_timer(&axp->t1);
  212.             axp->reason = LB_DM;
  213.             lapbstate(axp,LAPB_DISCONNECTED);
  214.             free_p(bp);
  215.             return 0;
  216. /*            break;    */
  217.         case UA:    /* Connection accepted */
  218.             /* Note: xmit queue not cleared */
  219.             stop_timer(&axp->t1);
  220.             start_timer(&axp->t3);
  221.             axp->unack = axp->vr = axp->vs = 0;
  222.             lapbstate(axp,LAPB_CONNECTED);
  223.             start_timer(&axp->t4);
  224.             break;
  225.         case DM:    /* Connection refused */
  226.             free_q(&axp->txq);
  227.             stop_timer(&axp->t1);
  228.             axp->reason = LB_DM;
  229.             lapbstate(axp,LAPB_DISCONNECTED);
  230.             free_p(bp);
  231.             return 0;
  232. /*            break;    */
  233.         default:    /* Respond with DM only to command polls */
  234.             if(poll)
  235.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  236.             break;
  237.         }
  238.         break;
  239.     case LAPB_DISCPENDING:
  240.         switch(type){
  241.         case SABM:
  242.             sendctl(axp,LAPB_RESPONSE,DM|pf);
  243.             drop_axr(axp);        /* drop ax25 route */
  244.             break;
  245.         case DISC:
  246.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  247.             drop_axr(axp);        /* drop ax25 route */
  248.             break;
  249.         case UA:
  250.         case DM:
  251.             stop_timer(&axp->t1);
  252.             lapbstate(axp,LAPB_DISCONNECTED);
  253.             free_p(bp);
  254.             return 0;
  255. /*            break;    */
  256.         default:    /* Respond with DM only to command polls */
  257.             if(poll)
  258.                 sendctl(axp,LAPB_RESPONSE,DM|pf);
  259.             drop_axr(axp);        /* drop ax25 route */
  260.             break;
  261.         }
  262.         break;
  263.     case LAPB_CONNECTED:
  264.         switch(type){
  265.         case SABM:
  266.            sendctl(axp,LAPB_RESPONSE,UA|pf);
  267. #ifdef SABM_HOLDOFF
  268.            if (axp->flags.rxd_I_frame) {
  269.                 /* only reset if we've had a */
  270.                 /* valid I-frame. Otherwise he */
  271.                 /* may just not have got our UA */
  272. #endif
  273.                 clr_ex(axp);
  274.                 free_q(&axp->txq);
  275.                 stop_timer(&axp->t1);
  276.                 start_timer(&axp->t3);
  277.                 axp->unack = axp->vr = axp->vs = 0;
  278.                 lapbstate(axp,LAPB_CONNECTED); /* Purge queues */
  279. #ifdef SABM_HOLDOFF
  280.             }
  281. #endif
  282.             break;
  283.         case DISC:
  284.             free_q(&axp->txq);
  285.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  286.             stop_timer(&axp->t1);
  287.             stop_timer(&axp->t3);
  288.             axp->reason = LB_NORMAL;
  289.             lapbstate(axp,LAPB_DISCONNECTED);
  290.             free_p(bp);
  291.             return 0;
  292. /*            break;    */
  293.         case DM:
  294.             axp->reason = LB_DM;
  295.             lapbstate(axp,LAPB_DISCONNECTED);
  296.             free_p(bp);
  297.             return 0;
  298. /*            break;    */
  299.         case UA:
  300.             est_link(axp);
  301.             lapbstate(axp,LAPB_SETUP);    /* Re-establish */    
  302.             break;            
  303.         case FRMR:
  304.             est_link(axp);
  305.             lapbstate(axp,LAPB_SETUP);    /* Re-establish link */
  306.             break;
  307.         case RR:
  308.         case RNR:
  309.             axp->flags.remotebusy = (type == RNR) ? YES : NO;
  310.             if(poll)
  311.                 enq_resp(axp);
  312.             else if (axp->pthresh == 65535)    /* -1 */
  313.                 stop_timer(&axp->t1);
  314.             ackours(axp,nr);
  315.             break;
  316.         case REJ:
  317.             axp->flags.remotebusy = NO;
  318.             if(poll)
  319.                 enq_resp(axp);
  320.             ackours(axp,nr);
  321.             stop_timer(&axp->t1);
  322.             start_timer(&axp->t3);
  323.             /* This may or may not actually invoke transmission,
  324.              * depending on whether this REJ was caused by
  325.              * our losing his prior ACK.
  326.              */
  327.             inv_rex(axp);
  328.             break;    
  329.         case I:
  330.             ackours(axp,nr); /** == -1) */
  331. #ifdef SABM_HOLDOFF
  332.             axp->flags.rxd_I_frame = 1;   /* we got something */
  333. #endif
  334.             start_timer(&axp->t4);
  335.             if(len_p(axp->rxq) >= axp->window){
  336.                 /* Too bad he didn't listen to us; he'll
  337.                  * have to resend the frame later. This
  338.                  * drastic action is necessary to avoid
  339.                  * deadlock.
  340.                  */
  341.                 if(poll)
  342.                     sendctl(axp,LAPB_RESPONSE,RNR|pf);
  343.                 free_p(bp);
  344.                 bp = NULLBUF;
  345.                 break;
  346.             }
  347.             /* Reject or ignore I-frames with receive sequence number errors */
  348.             if(ns != axp->vr){
  349.                 if(axp->proto == V1 || !axp->flags.rejsent){
  350.                     axp->flags.rejsent = YES;
  351.                     sendctl(axp,LAPB_RESPONSE,REJ | pf);
  352.                 } else if(poll)
  353.                     enq_resp(axp);
  354.                 axp->response = 0;
  355.                 break;
  356.             }
  357.             axp->flags.rejsent = NO;
  358.             axp->vr = (axp->vr+1) & MMASK;
  359.             tmp = len_p(axp->rxq) >= axp->window ? RNR : RR;
  360.             if(poll){
  361.                 sendctl(axp,LAPB_RESPONSE,tmp|PF);
  362.             } else {
  363.                 axp->response = tmp;
  364.             }
  365.             procdata(axp,bp);
  366.             bp = NULLBUF;
  367.             break;
  368.         default:    /* All others ignored */
  369.             break;
  370.         }
  371.         break;
  372.     case LAPB_RECOVERY:
  373.         switch(type){
  374.         case SABM:
  375.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  376. #ifdef SABM_HOLDOFF
  377.            if (axp->flags.rxd_I_frame) {
  378.                 /* only reset if we've had a */
  379.                 /* valid I-frame. Otherwise he */
  380.                 /* may just not have got our UA */
  381. #endif
  382.                 clr_ex(axp);
  383.                 stop_timer(&axp->t1);
  384.                 start_timer(&axp->t3);
  385.                 axp->unack = axp->vr = axp->vs = 0;
  386.                 lapbstate(axp,LAPB_CONNECTED); /* Purge queues */
  387.                 if(!run_timer(&axp->t4))
  388.                     start_timer(&axp->t4);
  389. #ifdef SABM_HOLDOFF
  390.             }
  391. #endif
  392.             break;
  393.         case DISC:
  394.             free_q(&axp->txq);
  395.             sendctl(axp,LAPB_RESPONSE,UA|pf);
  396.             stop_timer(&axp->t1);
  397.             stop_timer(&axp->t3);
  398.             axp->response = UA;
  399.             axp->reason = LB_NORMAL;
  400.             lapbstate(axp,LAPB_DISCONNECTED);
  401.             free_p(bp);
  402.             return 0;
  403. /*            break;    */
  404.         case DM:
  405. #ifdef NETROM
  406.             nr_derate(axp);
  407. #endif
  408.             axp->reason = LB_DM;
  409.             lapbstate(axp,LAPB_DISCONNECTED);
  410.             free_p(bp);
  411.             return 0;
  412. /*            break;    */
  413.         case UA:
  414.             est_link(axp);
  415.             lapbstate(axp,LAPB_SETUP);    /* Re-establish */    
  416.             break;
  417.         case FRMR:
  418.             est_link(axp);
  419.             lapbstate(axp,LAPB_SETUP);    /* Re-establish link */
  420.             break;
  421.         case RR:
  422.         case RNR:
  423.             axp->flags.remotebusy = (control == RNR) ? YES : NO;
  424.             if(axp->proto == V1 || final){
  425.                 stop_timer(&axp->t1);
  426.                 ackours(axp,nr);
  427.                 if(axp->unack != 0){
  428.                     inv_rex(axp);
  429.                 } else {
  430.                     start_timer(&axp->t3);
  431.                     lapbstate(axp,LAPB_CONNECTED);
  432.                     if(!run_timer(&axp->t4))
  433.                         start_timer(&axp->t4);
  434.                 }
  435.             } else {
  436.                 if(poll)
  437.                     enq_resp(axp);
  438.                 ackours(axp,nr);
  439.                 /* Keep timer running even if all frames
  440.                  * were acked, since we must see a Final
  441.                  */
  442.                 if(!run_timer(&axp->t1))
  443.                     start_timer(&axp->t1);
  444.             }
  445.             break;
  446.         case REJ:
  447.             axp->flags.remotebusy = NO;
  448.             /* Don't insist on a Final response from the old proto */
  449.             if(axp->proto == V1 || final){
  450.                 stop_timer(&axp->t1);
  451.                 ackours(axp,nr);
  452.                 if(axp->unack != 0){
  453.                     inv_rex(axp);
  454.                 } else {
  455.                     start_timer(&axp->t3);
  456.                     lapbstate(axp,LAPB_CONNECTED);
  457.                     if(!run_timer(&axp->t4))
  458.                         start_timer(&axp->t4);
  459.                 }
  460.             } else {
  461.                 if(poll)
  462.                     enq_resp(axp);
  463.                 ackours(axp,nr);
  464.                 if(axp->unack != 0){
  465.                     /* This is certain to trigger output */
  466.                     inv_rex(axp);
  467.                 }
  468.                 /* A REJ that acks everything but doesn't
  469.                  * have the F bit set can cause a deadlock.
  470.                  * So make sure the timer is running.
  471.                  */
  472.                 if(!run_timer(&axp->t1))
  473.                     start_timer(&axp->t1);
  474.             }
  475.             break;
  476.         case I:
  477.             ackours(axp,nr); /** == -1) */
  478. #ifdef SABM_HOLDOFF
  479.             axp->flags.rxd_I_frame = YES;   /* we got something */
  480. #endif
  481.             /* Make sure timer is running, since an I frame
  482.              * cannot satisfy a poll
  483.              */
  484.             if(!run_timer(&axp->t1))
  485.                 start_timer(&axp->t1);
  486.             if(len_p(axp->rxq) >= axp->window){
  487.                 /* Too bad he didn't listen to us; he'll
  488.                  * have to resend the frame later. This
  489.                  * drastic action is necessary to avoid
  490.                  * memory deadlock.
  491.                  */
  492.                 sendctl(axp,LAPB_RESPONSE,RNR | pf);
  493.                 free_p(bp);
  494.                 bp = NULLBUF;
  495.                 break;
  496.             }
  497.             /* Reject or ignore I-frames with receive sequence number errors */
  498.             if(ns != axp->vr){
  499.                 if(axp->proto == V1 || !axp->flags.rejsent){
  500.                     axp->flags.rejsent = YES;
  501.                     sendctl(axp,LAPB_RESPONSE,REJ | pf);
  502.                 } else if(poll)
  503.                     enq_resp(axp);
  504.  
  505.                 axp->response = 0;
  506.                 break;
  507.             }
  508.             axp->flags.rejsent = NO;
  509.             axp->vr = (axp->vr+1) & MMASK;
  510.             tmp = len_p(axp->rxq) >= axp->window ? RNR : RR;
  511.             if(poll){
  512.                 sendctl(axp,LAPB_RESPONSE,tmp|PF);
  513.             } else {
  514.                 axp->response = tmp;
  515.             }
  516.             procdata(axp,bp);
  517.             bp = NULLBUF;
  518.             break;
  519.         default:
  520.             break;        /* Ignored */
  521.         }
  522.         break;
  523.     }
  524.     free_p(bp);    /* In case anything's left */
  525.  
  526.     /* See if we can send some data, perhaps piggybacking an ack.
  527.      * If successful, lapb_output will clear axp->response.
  528.      */
  529.     lapb_output(axp);
  530.     if(axp->response != 0){
  531.         sendctl(axp,LAPB_RESPONSE,axp->response);
  532.         axp->response = 0;
  533.     }
  534.     return 0;
  535. }
  536.  
  537. /* Handle incoming acknowledgements for frames we've sent.
  538.  * Free frames being acknowledged.
  539.  * Return -1 to cause a frame reject if number is bad, 0 otherwise
  540.  */
  541. static int
  542. ackours(axp,n)
  543. struct ax25_cb *axp;
  544. int16 n;
  545. {    
  546.     struct mbuf *bp;
  547.     int acked = 0;    /* Count of frames acked by this ACK */
  548.     int16 oldest;    /* Seq number of oldest unacked I-frame */
  549.     int32 rtt,abserr;
  550.  
  551.     /* Free up acknowledged frames by purging frames from the I-frame
  552.      * transmit queue. Start at the remote end's last reported V(r)
  553.      * and keep going until we reach the new sequence number.
  554.      * If we try to free a null pointer,
  555.      * then we have a frame reject condition.
  556.      */
  557.     oldest = (axp->vs - axp->unack) & MMASK;
  558.     while(axp->unack != 0 && oldest != n){
  559.         if((bp = dequeue(&axp->txq)) == NULLBUF){
  560.             /* Acking unsent frame */
  561.             return -1;
  562.         }
  563.         free_p(bp);
  564.         axp->unack--;
  565.         acked++;
  566.         if(axp->flags.rtt_run && axp->rtt_seq == oldest){
  567.             /* A frame being timed has been acked */
  568.             axp->flags.rtt_run = 0;
  569.             /* Update only if frame wasn't retransmitted */
  570.             if(!axp->flags.retrans){
  571.                 rtt = msclock() - axp->rtt_time;
  572.                 abserr = (rtt > axp->srt) ? rtt - axp->srt :
  573.                  axp->srt - rtt;
  574.  
  575.                 /* Run SRT and mdev integrators */
  576.                 axp->srt = ((axp->srt * 7) + rtt + 4) >> 3;
  577.                 axp->mdev = ((axp->mdev*3) + abserr + 2) >> 2;
  578.                 /* Update timeout */
  579.                 set_timer(&axp->t1,4*axp->mdev+axp->srt);
  580.             }
  581.         }
  582.         axp->flags.retrans = 0;
  583.         axp->retries = 0;
  584.         oldest = (oldest + 1) & MMASK;
  585.     }
  586.     if(axp->unack == 0){
  587.         /* All frames acked, stop timeout */
  588.         stop_timer(&axp->t1);
  589.         start_timer(&axp->t3);
  590.     } else if(acked != 0) { 
  591.         /* Partial ACK; restart timer */
  592.         start_timer(&axp->t1);
  593.     }
  594.     if(acked != 0){
  595.         /* If user has set a transmit upcall, indicate how many frames
  596.          * may be queued
  597.          */
  598.         if(axp->t_upcall != NULLVFP)
  599.             (*axp->t_upcall)(axp,axp->paclen * (axp->maxframe - axp->unack));
  600.     }
  601.     return 0;
  602. }
  603.  
  604. /* Establish data link */
  605. void
  606. est_link(axp)
  607. struct ax25_cb *axp;
  608. {
  609.     clr_ex(axp);
  610.     axp->retries = 0;
  611.     sendctl(axp,LAPB_COMMAND,SABM|PF);
  612.     stop_timer(&axp->t3);
  613.     start_timer(&axp->t1);
  614. }
  615. /* Clear exception conditions */
  616. static void
  617. clr_ex(axp)
  618. struct ax25_cb *axp;
  619. {
  620.     axp->flags.remotebusy = NO;
  621.     axp->flags.rejsent = NO;
  622.     axp->response = 0;
  623.     stop_timer(&axp->t3);
  624. }
  625. /* Enquiry response */
  626. static void
  627. enq_resp(axp)
  628. struct ax25_cb *axp;
  629. {
  630.     char ctl;
  631.  
  632.     ctl = len_p(axp->rxq) >= axp->window ? RNR|PF : RR|PF;    
  633.     sendctl(axp,LAPB_RESPONSE,ctl);
  634.     axp->response = 0;
  635.     stop_timer(&axp->t3);
  636. }
  637. /* Invoke retransmission */
  638. static void
  639. inv_rex(axp)
  640. struct ax25_cb *axp;
  641. {
  642.     axp->vs -= axp->unack;
  643.     axp->vs &= MMASK;
  644.     axp->unack = 0;
  645. }
  646. /* Send S or U frame to currently connected station */
  647. int
  648. sendctl(axp,cmdrsp,cmd)
  649. struct ax25_cb *axp;
  650. int cmdrsp;
  651. int cmd;
  652. {
  653.     if((ftype((char)cmd) & 0x3) == S)    /* Insert V(R) if S frame */
  654.         cmd |= (axp->vr << 5);
  655.     return sendframe(axp,cmdrsp,cmd,NULLBUF);
  656. }
  657. /* Start data transmission on link, if possible
  658.  * Return number of frames sent
  659.  */
  660. int
  661. lapb_output(axp)
  662. register struct ax25_cb *axp;
  663. {
  664.     register struct mbuf *bp;
  665.     struct mbuf *tbp;
  666.     char control;
  667.     int sent = 0;
  668.     int i;
  669.  
  670.     if(axp == NULLAX25
  671.      || (axp->state != LAPB_RECOVERY && axp->state != LAPB_CONNECTED)
  672.      || axp->flags.remotebusy)
  673.         return 0;
  674.  
  675.     /* Dig into the send queue for the first unsent frame */
  676.     bp = axp->txq;
  677.     for(i = 0; i < axp->unack; i++){
  678.         if(bp == NULLBUF)
  679.             break;    /* Nothing to do */
  680.         bp = bp->anext;
  681.     }
  682.     /* Start at first unsent I-frame, stop when either the
  683.      * number of unacknowledged frames reaches the maxframe limit,
  684.      * or when there are no more frames to send
  685.      */
  686.     while(bp != NULLBUF && axp->unack < axp->maxframe){
  687.         control = I | (axp->vs++ << 1) | (axp->vr << 5);
  688.         axp->vs &= MMASK;
  689.         dup_p(&tbp,bp,0,len_p(bp));
  690.         if(tbp == NULLBUF)
  691.             return sent;    /* Probably out of memory */
  692.         sendframe(axp,LAPB_COMMAND,control,tbp);
  693.         start_timer(&axp->t4);
  694.         axp->unack++;
  695.         /* We're implicitly acking any data he's sent, so stop any
  696.          * delayed ack
  697.          */
  698.         axp->response = 0;
  699.         if(!run_timer(&axp->t1)){
  700.             stop_timer(&axp->t3);
  701.             start_timer(&axp->t1);
  702.         }
  703.         sent++;
  704.         bp = bp->anext;
  705.         if(!axp->flags.rtt_run){
  706.             /* Start round trip timer */
  707.             axp->rtt_seq = (control >> 1) & MMASK;
  708.             axp->rtt_time = msclock();
  709.             axp->flags.rtt_run = 1;
  710.         }
  711.     }
  712.     return sent;
  713. }
  714. /* Set new link state */
  715. void
  716. lapbstate(axp,s)
  717. struct ax25_cb *axp;
  718. int s;
  719. {
  720.     int oldstate;
  721.  
  722.     oldstate = axp->state;
  723.     axp->state = s;
  724.     if(s == LAPB_DISCONNECTED){
  725.         stop_timer(&axp->t1);
  726.         stop_timer(&axp->t3);
  727.         stop_timer(&axp->t4);
  728.         free_q(&axp->txq);
  729.         drop_axr(axp);        /* any ax25 route that hasn't been dropped yet*/
  730.     }
  731.     /* Don't bother the client unless the state is really changing */
  732.     if((oldstate != s) && (axp->s_upcall != NULLVFP))
  733.         (*axp->s_upcall)(axp,oldstate,s);
  734. }
  735. /* Process a valid incoming I frame */
  736. static void
  737. procdata(axp,bp)
  738. struct ax25_cb *axp;
  739. struct mbuf *bp;
  740. {
  741.     int pid;
  742.     int seq;
  743.  
  744.     /* Extract level 3 PID */
  745.     if((pid = PULLCHAR(&bp)) == -1)
  746.         return;    /* No PID */
  747.  
  748.     if(axp->segremain != 0){
  749.         /* Reassembly in progress; continue */
  750.         seq = PULLCHAR(&bp);
  751.         if(pid == PID_SEGMENT
  752.          && (seq & SEG_REM) == axp->segremain - 1){
  753.             /* Correct, in-order segment */
  754.             append(&axp->rxasm,bp);
  755.             if((axp->segremain = (seq & SEG_REM)) == 0){
  756.                 /* Done; kick it upstairs */
  757.                 bp = axp->rxasm;
  758.                 axp->rxasm = NULLBUF;
  759.                 pid = PULLCHAR(&bp);
  760.                 handleit(axp,pid,bp);
  761.             }
  762.         } else {
  763.             /* Error! */
  764.             free_p(axp->rxasm);
  765.             axp->rxasm = NULLBUF;
  766.             axp->segremain = 0;
  767.             free_p(bp);
  768.         }
  769.     } else {
  770.         /* No reassembly in progress */
  771.         if(pid == PID_SEGMENT){
  772.             /* Start reassembly */
  773.             seq = PULLCHAR(&bp);
  774.             if(!(seq & SEG_FIRST)){
  775.                 free_p(bp);    /* not first seg - error! */
  776.             } else {
  777.                 /* Put first segment on list */
  778.                 axp->segremain = seq & SEG_REM;
  779.                 axp->rxasm = bp;
  780.             }
  781.         } else {
  782.             /* Normal frame; send upstairs */
  783.             handleit(axp,pid,bp);
  784.         }
  785.     }
  786. }
  787. /* New-style frame segmenter. Returns queue of segmented fragments, or
  788.  * original packet if small enough
  789.  */
  790. struct mbuf *
  791. segmenter(bp,ssize)
  792. struct mbuf *bp;    /* Complete packet */
  793. int16 ssize;        /* Max size of frame segments */
  794. {
  795.     struct mbuf *result = NULLBUF;
  796.     struct mbuf *bptmp,*bp1;
  797.     int16 len,offset;
  798.     int segments;
  799.  
  800.     /* See if packet is too small to segment. Note 1-byte grace factor
  801.      * so the PID will not cause segmentation of a 256-byte IP datagram.
  802.      */
  803.     len = len_p(bp);
  804.     if(len <= ssize+1)
  805.         return bp;    /* Too small to segment */
  806.  
  807.     ssize -= 2;        /* ssize now equal to data portion size */
  808.     segments = 1 + (len - 1) / ssize;    /* # segments  */
  809.     offset = 0;
  810.  
  811.     while(segments != 0){
  812.         offset += dup_p(&bptmp,bp,offset,ssize);
  813.         if(bptmp == NULLBUF){
  814.             free_q(&result);
  815.             break;
  816.         }
  817.         /* Make room for segmentation header */
  818.         if((bp1 = pushdown(bptmp,2)) == NULLBUF){
  819.             free_p(bptmp);
  820.             free_q(&result);
  821.             break;
  822.         }
  823.         bp1->data[0] = PID_SEGMENT;
  824.         bp1->data[1] = --segments;
  825.         if(offset == ssize)
  826.             bp1->data[1] |= SEG_FIRST;
  827.         enqueue(&result,bp1);
  828.     }
  829.     free_p(bp);
  830.     return result;
  831. }
  832.  
  833. static void
  834. handleit(axp,pid,bp)
  835. struct ax25_cb *axp;
  836. int pid;
  837. struct mbuf *bp;
  838. {
  839.     struct axlink *ipp;
  840.  
  841.     for(ipp = Axlink;ipp->funct != NULL;ipp++){
  842.         if(ipp->pid == pid)
  843.             break;
  844.     }
  845.     if(ipp->funct != NULL)
  846.         (*ipp->funct)(axp->iface,axp,NULLCHAR,NULLCHAR,bp,0);
  847.     else
  848.         free_p(bp);
  849. }
  850.  
  851. #endif /* AX25 */
  852.  
  853.